﻿using IRemoting;
using QLNH.MyLayouts;
using QLNH.QLNH_BUS_WS;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using System.Threading;
using System.Net.Sockets;
using System.IO;

namespace QLNH
{
    public partial class MainForm : Form
    {
        #region Properties

        private TcpClient tcpClient;
        public TcpClient TCPClient
        {
            get { return tcpClient; }
            set { tcpClient = value; }
        }

        private AccountDetailDTO currentUser = null;
        public AccountDetailDTO CurrentUser
        {
            get { return currentUser; }
            set { currentUser = value; }
        }

        private LayoutUC currentLayout;

        #endregion

        #region Constructor

        public MainForm()
        {
            InitializeComponent();
        }

        #endregion

        #region Functions

        //chuyen qua lai giua cac layout
        public void SwictchLayout(LayoutKey key)
        {
            switch (key)
            {
                case LayoutKey.LOGIN_LAYOUT:
                    InstallLayout(new LayoutLogin(this));
                    break;
                case LayoutKey.ADMIN_LAYOUT:
                    InstallLayout(new LayoutAdmin(this));
                    break;
                case LayoutKey.CHEF_LAYOUT:
                    InstallLayout(new LayoutChef(this));
                    break;
                case LayoutKey.RECEPTION_LAYOUT:
                    InstallLayout(new LayoutReception(this));
                    break;
                case LayoutKey.CASHIER_LAYOUT:
                    InstallLayout(new LayoutCashier(this));
                    break;
                default:
                    break;
            }
        }

        //hien thi mot layout
        public void InstallLayout(LayoutUC layout)
        {
            layout.Resize(this.pn_content.Size);
            pn_content.BeginInvoke((MethodInvoker)(() => pn_content.Controls.Clear()));
            pn_content.BeginInvoke((MethodInvoker)(() => pn_content.Controls.Add(layout)));
            currentLayout = layout;
        }

        //lay thong tin nha hang
        public void GetInfo()
        {
            Thread t = new Thread(new ThreadStart(GetInfoFromDB));
            t.SetApartmentState(ApartmentState.STA);
            t.Start();
        }

        private void GetInfoFromDB()
        {
            QLNH_BUS_WebServiceSoapClient ws = new QLNH_BUS_WebServiceSoapClient();
            InfoDTO info = ws.GetInfo();
            lb_name.BeginInvoke((MethodInvoker)(() => lb_name.Text = info.Name));
            lb_address.BeginInvoke((MethodInvoker)(() => lb_address.Text = info.Address));
            lb_phoneNumber.BeginInvoke((MethodInvoker)(() => lb_phoneNumber.Text = info.PhoneNumber));
        }

        #region Communication

        private void ConnectToServer()
        {
            int portNumber = Int32.Parse(ConfigurationManager.AppSettings["PortNumber"].ToString());
            string serverIP = ConfigurationManager.AppSettings["RemoteServerIP"].ToString();

            tcpClient = new TcpClient();

            try
            {
                tcpClient.Connect(serverIP, portNumber);
                Worker worker = new Worker(this, tcpClient.GetStream());
                worker.work();
            }
            catch
            {
                MessageBox.Show("Không thể kết nối máy chủ");
                Close();
            }
        }

        // Send log in request to remote server
        public string login(string userName)
        {
            QLNH_BUS_WebServiceSoapClient ws = new QLNH_BUS_WebServiceSoapClient();

            currentUser = ws.GetAccoutInfo(userName);
            if (currentUser != null)
            {
                if (currentUser.Role.Equals(Role.waiter.ToString()))
                {
                    currentUser = null;
                    return "* Không thể đăng nhập bằng tài khoản " + Role.waiter.ToString();
                }

                BasePackage package = new BasePackage();
                package.setHeader(PackageHeader.LOGIN_REQ);
                package.setUserName(userName);

                Stream stream = tcpClient.GetStream();
                StreamWriter writer = new StreamWriter(stream);
                writer.AutoFlush = true;

                try
                {
                    writer.WriteLine(package.convertToString());
                }
                catch
                {
                    MessageBox.Show("Có vấn đề khi kết nối với máy chủ, phần mềm sẽ kết thúc");
                    Close();
                }
                return null;
            }
            else
            {
                return "* Tài khoản không tồn tại";
            }
        }

        // Send readty to serve order no broadcast message
        public void readyToServer(int orderNo)
        {

            QLNH_BUS_WebServiceSoapClient ws = new QLNH_BUS_WebServiceSoapClient();
            ws.UpdateOrderState(orderNo, State.ReadyToServe);

            BasePackage package = new BasePackage();
            package.setHeader(PackageHeader.SEND_BROADCAST_MESSAGE);
            package.setBroadcastMassageHeader(BroadcastMassgeHeader.READY_TO_SERVE_ORDER);
            package.setBroadcastMassage(orderNo);

            Stream stream = tcpClient.GetStream();
            StreamWriter writer = new StreamWriter(stream);
            writer.AutoFlush = true;

            try
            {
                writer.WriteLine(package.convertToString());
            }
            catch
            {
                MessageBox.Show("Có vấn đề khi kết nối với máy chủ, phần mềm sẽ kết thúc");
                Close();
            }
        }

        // Send checked out order broadcast message at table [ID]
        public void checkedOut(string tableID)
        {
            BasePackage package = new BasePackage();
            package.setHeader(PackageHeader.SEND_BROADCAST_MESSAGE);
            package.setBroadcastMassageHeader(BroadcastMassgeHeader.CHECKED_OUT_ORDER);
            package.setBroadcastMassage(tableID);

            StreamWriter writer = new StreamWriter(tcpClient.GetStream());
            writer.AutoFlush = true;

            try
            {
                writer.WriteLine(package.convertToString());
            }
            catch
            {
                MessageBox.Show("Có vấn đề khi kết nối với máy chủ, phần mềm sẽ kết thúc");
                Close();
            }
        }

        // Worker to receive massage and send to layout
        public class Worker
        {
            private Stream stream;
            private MainForm mainForm;

            public Worker(MainForm mainForm, Stream stream)
            {
                this.mainForm = mainForm;
                this.stream = stream;
            }

            public void work()
            {
                Thread t = new Thread(new ThreadStart(doWork));
                t.SetApartmentState(ApartmentState.MTA);
                t.IsBackground = true;
                t.Start();
            }

            private void doWork()
            {
                while (true)
                {
                    StreamReader reader = new StreamReader(stream);

                    string message = null;
                    try
                    {
                        message = reader.ReadLine();
                    }
                    catch
                    {
                        break;
                    }

                    if (message == null)
                    {
                        break;
                    }

                    BasePackage package = new BasePackage();
                    package.convertFromString(message);
                    mainForm.currentLayout.OnReceivePackage(package);
                }
            }
        }

        #endregion 

        //dang xuat khoi he thong
        private void Logout()
        {
            if (currentUser != null)
            {
                BasePackage package = new BasePackage();
                package.setHeader(PackageHeader.LOGOUT_REQ);
                package.setUserName(currentUser.UserName);

                try
                {
                    Stream stream = tcpClient.GetStream();
                    StreamWriter writer = new StreamWriter(stream);
                    writer.AutoFlush = true;

                    writer.WriteLine(package.convertToString());
                    currentUser = null;

                }
                catch
                {
                    currentUser = null;
                    MessageBox.Show("Có vấn đề khi kết nối với máy chủ, phần mềm sẽ kết thúc");
                    Close();
                }
            }
        }

        #endregion

        #region Control Events

        private void MainForm_Resize(object sender, EventArgs e)
        {
            if (this.pn_content.Controls.Count > 0)
            {
                ((LayoutUC)this.pn_content.Controls[0]).Resize(this.pn_content.Size);
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            ConnectToServer();
            SwictchLayout(LayoutKey.LOGIN_LAYOUT);
            GetInfo();
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            Logout();
        }

        private void pb_logout_MouseClick(object sender, MouseEventArgs e)
        {
            Logout();
            SwictchLayout(LayoutKey.LOGIN_LAYOUT);
            this.pn_right.Visible = false;
        }

        #endregion
    }
}
